// dart_type_system_examples.dart

// --- 类型别名 (Typedefs) ---

// 为 List<int> 定义一个类型别名 IntList
typedef IntList = List<int>;

// 为泛型 Map<X, List<X>> 定义一个类型别名 ListMapper<X>
typedef ListMapper<X> = Map<X, List<X>>;

// 为函数类型定义一个类型别名 Compare<T> (旧版用法，但仍然有用)
typedef Compare<T> = int Function(T a, T b);

// 一个符合 Compare<int> 签名的函数
int sort(int a, int b) => a - b;

// --- 基础类型安全与静态分析 ---

// 一个接受整数列表的函数
void printInts(List<int> a) => print('printInts: $a');

// --- 类定义 ---

// 动物基类
class Animal {
  void chase(Animal a) {
    print('Animal chasing another Animal');
  }

  // 使用可空类型更实际
  Animal? get parent => null;

  @override
  String toString() => runtimeType.toString(); // 方便打印类型
}

// 蜜獾类，继承自动物
class HoneyBadger extends Animal {
  @override
  void chase(Object a) {
    // 参数类型放宽 (Object 是 Animal 的父类型) - OK
    print('HoneyBadger chasing an Object: $a');
  }

  @override
  HoneyBadger? get parent => null; // 返回值类型收窄 (HoneyBadger 是 Animal 的子类型) - OK
}

// 鼠标类
class Mouse extends Animal {}

// 猫类
class Cat extends Animal {
  // @override
  // void chase(Mouse a) { // 错误: 参数类型不能收窄 (Mouse 是 Animal 的子类型)
  //   print('Cat chasing a Mouse');
  // }
  // 上面的代码会产生静态分析错误，除非使用 covariant (见下文)

  @override
  void chase(Animal a) {
    // 保持父类参数类型
    if (a is Mouse) {
      print('Cat chasing a specific Mouse!');
    } else {
      print('Cat chasing an Animal');
    }
  }
}

// 缅因猫类
class MaineCoon extends Cat {}

// 狗类
class Dog extends Animal {}

// --- F-Bounded 类型示例 ---
class A<X extends A<X>> {}

class B extends A<B> {}

class C extends B {}

// 接受 F-Bounded 类型参数的函数
void f<X extends A<X>>(X x) {
  print('f<$X> called with instance of type ${x.runtimeType}');
}

// --- Comparable 示例 ---
// 查找两个可比较对象中较大的一个
// X 必须是 Comparable<X> 的子类型
X max<X extends Comparable<X>>(X x1, X x2) {
  print('Comparing $x1 and $x2');
  return x1.compareTo(x2) > 0 ? x1 : x2;
}

// --- 类型解构辅助类 (替代 Record) ---
class Pair<T1, T2> {
  final T1 first;
  final T2 second;
  Pair(this.first, this.second);

  @override
  String toString() =>
      'Pair(first: $first [${first.runtimeType}], second: $second [${second.runtimeType}])';
}

// 模拟类型解构的函数
// X 是 Iterable<Y> 的子类型
Pair<X, Y> f1<X extends Iterable<Y>, Y>(X x) {
  print('f1 called with Iterable of type $X containing elements of type $Y');
  return Pair(x, x.first);
}

// --- 静态字段推断示例 ---
class Counter {
  // count 会被推断为 int 类型
  static var count = 0;
  // 如果是 static var count = 0.0; 则会被推断为 double
}

// --- Covariant 示例 ---
class AnimalCovariant {
  void chase(AnimalCovariant x) {
    print('AnimalCovariant chasing AnimalCovariant');
  }
}

class MouseCovariant extends AnimalCovariant {}

class CatCovariant extends AnimalCovariant {
  // 使用 covariant 关键字允许参数类型收窄
  // 这会移除静态错误，但在运行时会进行检查
  @override
  void chase(covariant MouseCovariant x) {
    print('CatCovariant chasing a specific MouseCovariant');
  }
}

// --- 主函数入口 ---
void main() {
  print('--- 1. 基础类型安全 ---');
  // 错误示例 1: 动态列表赋值给类型化列表 (静态分析失败)
  // final list_dynamic = []; // 推断为 List<dynamic>
  // list_dynamic.add(1);
  // list_dynamic.add('2'); // 动态列表可以添加不同类型
  // printInts(list_dynamic); // 错误: The argument type 'List<dynamic>' can't be assigned to the parameter type 'List<int>'.

  // 正确示例 1: 使用类型注解
  final listInt = <int>[]; // 明确类型为 List<int>
  listInt.add(1);
  listInt.add(2);
  // list_int.add('3'); // 错误: The argument type 'String' can't be assigned to the parameter type 'int'.
  printInts(listInt); // 输出: printInts: [1, 2]

  print('\n--- 2. 方法重写 (返回值和参数类型) ---');
  var honeyBadger = HoneyBadger();
  honeyBadger.chase(Animal()); // OK, 参数类型放宽
  HoneyBadger? parentBadger = honeyBadger.parent; // OK, 返回值类型收窄
  print(
    'HoneyBadger parent type: ${parentBadger?.runtimeType}',
  ); // 输出: HoneyBadger parent type: null (因为我们返回了 null)

  // 错误示例 2: 参数类型收窄 (无 covariant)
  // Cat().chase(Animal()); // 如果 Cat.chase 参数是 Mouse，这里会报错或需要类型转换

  print('\n--- 3. 动态列表与类型化列表 ---');
  // 错误示例 3: 将包含 Dog 的动态列表赋值给 List<Cat> (静态分析失败)
  // List<Cat> foo = <dynamic>[Dog()]; // 错误: A value of type 'List<dynamic>' can't be assigned to a variable of type 'List<Cat>'.

  // OK 示例: 动态列表可以包含不同类型的 Animal
  List<dynamic> bar = <dynamic>[Dog(), Cat()];
  print('Dynamic list bar: $bar'); // 输出: Dynamic list bar: [Dog, Cat]

  // 错误示例 4: 运行时类型转换失败
  try {
    List<Animal> animals = <Dog>[Dog()]; // 实际上是 List<Dog>
    // 下面的转换会在运行时失败，因为 List<Dog> 不能被当作 List<Cat>
    List<Cat> cats = animals as List<Cat>;
    print('Cats after cast (will not reach here): $cats');
  } catch (e) {
    print(
      'Runtime cast error caught: $e',
    ); // 输出: Runtime cast error caught: ..._TypeError (...)
  }

  print('\n--- 4. 类型推断 ---');
  // Map 推断
  Map<String, dynamic> argumentsExplicit = {'argA': 'hello', 'argB': 42};
  var argumentsInferred = {
    'argA': 'hello',
    'argB': 42,
  }; // 推断为 Map<String, Object>
  print(
    'Explicit Map: $argumentsExplicit, Type: ${argumentsExplicit.runtimeType}',
  );
  print(
    'Inferred Map: $argumentsInferred, Type: ${argumentsInferred.runtimeType}',
  ); // 输出: Inferred Map: {argA: hello, argB: 42}, Type: _Map<String, Object>

  // 静态字段推断
  print(
    'Static Counter.count type: ${Counter.count.runtimeType}',
  ); // 输出: Static Counter.count type: int

  // 局部变量推断
  // var x = 3; // 推断为 int
  // x = 4.0; // 错误: A value of type 'double' can't be assigned to a variable of type 'int'.
  num y = 3; // 显式声明为 num
  y = 4.0; // OK, num 可以是 int 或 double
  print(
    'Variable y: $y, Type: ${y.runtimeType}',
  ); // 输出: Variable y: 4.0, Type: double

  // 泛型参数推断
  List<int> listOfInt = [1, 2, 3]; // 推断为 List<int>
  print('使用 List<int>: $listOfInt'); // 打印使用这个变量
  var listOfDouble = [3.0]; // 推断为 List<double>
  var ints = listOfDouble.map((x) {
    // x 被推断为 double (来自 listOfDouble)
    print('Mapping double $x (${x.runtimeType}) to int');
    return x.toInt(); // 返回类型是 int
  }); // ints 被推断为 Iterable<int>
  print(
    'Inferred Iterable<int>: ${ints.toList()}, Type: ${ints.runtimeType}',
  ); // 输出: Inferred Iterable<int>: [3], Type: MappedListIterable<double, int>

  print('\n--- 5. 类型推断 (Bounds) ---');
  // F-Bounded 类型推断
  f(B()); // 推断 f<B>(B())
  f(C()); // 推断 f<C>(C()) - C 是 B 的子类，B 是 A<B> 的子类
  f<B>(C()); // 显式指定类型参数

  // Comparable 类型推断
  var maxNum = max(3, 7.0); // 推断 max<num>(3, 7.0) 因为 3 和 7.0 的共同父类是 num
  print(
    'Max of 3 and 7.0 is $maxNum, Type: ${maxNum.runtimeType}',
  ); // 输出: Max of 3 and 7.0 is 7.0, Type: double
  var maxInt = max(5, 2); // 推断 max<int>(5, 2)
  print(
    'Max of 5 and 2 is $maxInt, Type: ${maxInt.runtimeType}',
  ); // 输出: Max of 5 and 2 is 5, Type: int

  // 类型解构推断 (使用 Pair 类模拟)
  var result1 = f1([1, 2, 3]); // 推断 f1<List<int>, int>([1, 2, 3])
  print(
    'f1 result for List: $result1',
  ); // 输出: Pair(first: [1, 2, 3] [List<int>], second: 1 [int])
  var myInt = result1.second;
  print(
    'Extracted int: $myInt, Type: ${myInt.runtimeType}',
  ); // 输出: Extracted int: 1, Type: int
  // myInt.whatever; // 编译时错误: The getter 'whatever' isn't defined for the type 'int'.

  var result2 = f1({'Hello!'}); // 推断 f1<Set<String>, String>({'Hello!'})
  print(
    'f1 result for Set: $result2',
  ); // 输出: Pair(first: {Hello!} [Set<String>], second: Hello! [String])
  var mySet = result2.first;
  print(
    'Extracted Set: $mySet, Type: ${mySet.runtimeType}',
  ); // 输出: Extracted Set: {Hello!}, Type: _Set<String>
  var unionSet = mySet.union({'World!'}); // OK, mySet 被正确推断为 Set<String>
  print('Union Set: $unionSet'); // 输出: Union Set: {Hello!, World!}

  print('\n--- 6. 类型替换 (协变与逆变) ---');
  // 普通类型赋值 (消费者位置)
  Animal c1 = Cat(); // OK: 可以将子类型(Cat)赋值给父类型(Animal)变量 (类型放宽)
  print(
    'Consumer widening: c1 is ${c1.runtimeType}',
  ); // 输出: Consumer widening: c1 is Cat
  // MaineCoon c2 = Cat(); // 错误: 不能将父类型(Cat)赋值给子类型(MaineCoon)变量 (类型收窄)

  // 普通类型赋值 (生产者位置)
  Cat c3 = MaineCoon(); // OK: 可以将更具体的类型(MaineCoon)赋值给基类型(Cat) (类型收窄)
  print(
    'Producer narrowing: c3 is ${c3.runtimeType}',
  ); // 输出: Producer narrowing: c3 is MaineCoon

  // 泛型类型赋值
  List<MaineCoon> myMaineCoons = [MaineCoon()];
  List<Cat> myCatsFromMC =
      myMaineCoons; // OK: List<MaineCoon> 是 List<Cat> 的子类型 (协变)
  print(
    'Generic covariant assignment: myCatsFromMC holds ${myCatsFromMC.runtimeType}',
  ); // 输出: Generic covariant assignment: myCatsFromMC holds List<MaineCoon>

  List<Animal> myAnimals = [Dog(), Cat()];
  // List<Cat> myCatsFromAnimal = myAnimals; // 错误: 不能将 List<Animal> 赋值给 List<Cat> (隐式向下转型不允许)
  try {
    // 显式转换，但如果 myAnimals 实际包含非 Cat 对象，运行时会失败
    List<Cat> myCatsFromAnimalExplicit = myAnimals as List<Cat>;
    print(
      'Explicit cast result (potential runtime error): $myCatsFromAnimalExplicit',
    );
  } catch (e) {
    print(
      'Runtime cast error for List caught: $e',
    ); // 输出: Runtime cast error for List caught: ..._TypeError (...)
  }

  print('\n--- 7. Covariant 关键字 ---');
  var catCov = CatCovariant();
  var mouseCov = MouseCovariant();
  // var animalCov = AnimalCovariant(); // 如果有 AnimalCovariant 实例

  catCov.chase(mouseCov); // OK, 因为 chase 方法参数是 MouseCovariant
  // catCov.chase(animalCov); // 运行时错误: Type 'AnimalCovariant' is not a subtype of type 'MouseCovariant' of 'x'
  // 上面的调用会失败，因为 CatCovariant 的 chase 方法期望 MouseCovariant，即使其父类方法接受 AnimalCovariant

  print('\n--- 8. 类型别名 (Typedef) ---');
  // 使用 IntList 类型别名
  IntList il = [1, 2, 3];
  print(
    'Using IntList typedef: $il, Type: ${il.runtimeType}',
  ); // 输出: Using IntList typedef: [1, 2, 3], Type: List<int>
  printInts(il); // OK: il 实际上是 List<int>

  // 使用 ListMapper 类型别名
  Map<String, List<String>> m1 = {
    'a': ['A'],
    'b': ['B'],
  }; // 完整写法
  ListMapper<String> m2 = {
    'c': ['C'],
    'd': ['D'],
  }; // 使用 typedef 的简洁写法
  print('Verbose Map: $m1, Type: ${m1.runtimeType}');
  print(
    'Typedef Map: $m2, Type: ${m2.runtimeType}',
  ); // 输出: Typedef Map: {c: [C], d: [D]}, Type: _Map<String, List<String>>

  // 使用函数类型别名 Compare<T>
  print('Checking if sort function conforms to Compare<int> typedef...');
  // 由于 sort 函数的签名已经完全匹配 Compare<int>，这里的类型检查是多余的
  print('sort 函数符合 Compare<int> 类型定义');
  print('Assertion passed: sort function is indeed a Compare<int>!');

  print('\n--- 示例代码执行完毕 ---');
}
